home *** CD-ROM | disk | FTP | other *** search
/ IRIS Performer 2.2 Friends Demo / SGI IRIS Performer 2.2 Friends Demo.iso / friends / openworlds / tix / SWindow.tcl < prev    next >
Text File  |  1997-11-22  |  6KB  |  257 lines

  1. # tixScrolledWindow --
  2. #
  3. #    Allows you to scroll any widget inside a scrolled area.
  4. #
  5. # Example:
  6. #    
  7. #    tixScrolledWindow .w
  8. #    set window [.w subwidget window]
  9. #        # Now you can put a whole widget hierachy inside $window.
  10. #        #
  11. #    button $window.b
  12. #    pack $window.b
  13. #
  14. # Author's note
  15. #
  16. # Note, the current implementation does not allow the child window
  17. # to be outside of the parent window when the parent's size is larger
  18. # than the child's size. This is fine for normal operations. However,
  19. # it is not suitable for an MDI master window. Therefore, you will notice
  20. # that the MDI master window is not a subclass of ScrolledWidget at all.
  21. #
  22. #
  23. tixWidgetClass tixScrolledWindow {
  24.     -classname TixScrolledWindow
  25.     -superclass tixScrolledWidget
  26.     -method {
  27.     }
  28.     -flag {
  29.     -expandmode -shrink -xscrollincrement -yscrollincrement
  30.     }
  31.     -static {
  32.     }
  33.     -configspec {
  34.     {-expandmode expandMode ExpandMode expand}
  35.     {-shrink shrink Shrink {}}
  36.     {-xscrollincrement xScrollIncrement ScrollIncrement {}}
  37.     {-yscrollincrement yScrollIncrement ScrollIncrement {}}
  38.     }
  39.     -default {
  40.     {.scrollbar            auto}
  41.     {*window.borderWidth        1}
  42.     {*f1.borderWidth        1}
  43.     {*Scrollbar.borderWidth        1}
  44.     {*Scrollbar.background        #d9d9d9}
  45.     {*Scrollbar.relief        sunken}
  46.     {*Scrollbar.troughColor        #c3c3c3}
  47.     {*Scrollbar.takeFocus        0}
  48.     {*Scrollbar.width        15}
  49.     }
  50. }
  51.  
  52. proc tixScrolledWindow::InitWidgetRec {w} {
  53.     upvar #0 $w data
  54.  
  55.     tixChainMethod $w InitWidgetRec
  56.  
  57.     set data(dx) 0
  58.     set data(dy) 0
  59. }
  60.  
  61. proc tixScrolledWindow::ConstructWidget {w} {
  62.     upvar #0 $w data
  63.  
  64.     set data(pw:f1) \
  65.     [frame $w.f1 -relief sunken]
  66.     set data(pw:f2) \
  67.     [frame $w.f2 -bd 0]
  68.     set data(w:window) \
  69.     [frame $w.f2.window -bd 0]
  70.     pack $data(pw:f2) -in $data(pw:f1) -expand yes -fill both
  71.  
  72.     set data(w:hsb) \
  73.     [scrollbar $w.hsb -orient horizontal -takefocus 0]
  74.     set data(w:vsb) \
  75.     [scrollbar $w.vsb -orient vertical -takefocus 0]
  76. #   set data(w:pann) \
  77. #    [frame $w.pann -bd 2 -relief groove]
  78.     
  79.     $data(pw:f1) config -highlightthickness \
  80.     [$data(w:hsb) cget -highlightthickness]
  81.  
  82.     set data(pw:client) $data(pw:f1)
  83. }
  84.  
  85. proc tixScrolledWindow::SetBindings {w} {
  86.     upvar #0 $w data
  87.  
  88.     tixChainMethod $w SetBindings
  89.  
  90.     $data(w:hsb) config -command "tixScrolledWindow::ScrollBarCB $w x"
  91.     $data(w:vsb) config -command "tixScrolledWindow::ScrollBarCB $w y"
  92.  
  93.     tixManageGeometry $data(w:window) "tixScrolledWindow::WindowGeomProc $w"
  94. }
  95.  
  96. # This guy just keeps asking for a same size as the w:window 
  97. #
  98. proc tixScrolledWindow::WindowGeomProc {w args} {
  99.     upvar #0 $w data
  100.  
  101.     set rw [winfo reqwidth  $data(w:window)]
  102.     set rh [winfo reqheight $data(w:window)]
  103.  
  104.     tixGeometryRequest $data(pw:f2) $rw $rh
  105. }
  106.  
  107. proc tixScrolledWindow::Scroll {w axis total window first args} {
  108.     upvar #0 $w data
  109.  
  110.     case [lindex $args 0] {
  111.     "scroll" {
  112.         set amt  [lindex $args 1]
  113.         set unit [lindex $args 2]
  114.  
  115.         case $unit {
  116.         "units" {
  117.             set incr $axis\scrollincrement
  118.             if {$data(-$incr) != {}} {
  119.             set by $data(-$incr)
  120.             } else {
  121.             set by [expr $window / 16]
  122.             }
  123.             set first [expr $first + $amt * $by]
  124.         }
  125.         "pages" {
  126.             set first [expr $first + $amt * $window]
  127.         }
  128.         }
  129.     }
  130.     "moveto" {
  131.         set to [lindex $args 1]
  132.         set first [expr int($to * $total)]
  133.     }
  134.     }
  135.  
  136.     if {[expr $first + $window] > $total} {
  137.     set first [expr $total - $window]
  138.     }
  139.     if {$first < 0} {
  140.     set first 0
  141.     }
  142.  
  143.     return $first
  144. }
  145.  
  146. proc tixScrolledWindow::ScrollBarCB {w axis args} {
  147.     upvar #0 $w data
  148.  
  149.     set bd \
  150.        [expr [$data(pw:f1) cget -bd] + [$data(pw:f1) cget -highlightthickness]]
  151.     set fw [expr [winfo width  $data(pw:f1)] - 2*$bd]
  152.     set fh [expr [winfo height $data(pw:f1)] - 2*$bd]
  153.     set ww [winfo reqwidth  $data(w:window)]
  154.     set wh [winfo reqheight $data(w:window)]
  155.  
  156.     if {$axis == "x"} {
  157.     set data(dx) \
  158.         [eval tixScrolledWindow::Scroll $w $axis $ww $fw $data(dx) $args]
  159.     } else {
  160.     set data(dy) \
  161.         [eval tixScrolledWindow::Scroll $w $axis $wh $fh $data(dy) $args]
  162.     }
  163.  
  164.     tixWidgetDoWhenIdle tixScrolledWindow::PlaceWindow $w
  165. }
  166.  
  167. proc tixScrolledWindow::PlaceWindow {w} {
  168.     upvar #0 $w data
  169.  
  170.     set bd \
  171.        [expr [$data(pw:f1) cget -bd] + [$data(pw:f1) cget -highlightthickness]]
  172.     set fw [expr [winfo width  $data(pw:f1)] - 2*$bd]
  173.     set fh [expr [winfo height $data(pw:f1)] - 2*$bd]
  174.     set ww [winfo reqwidth  $data(w:window)]
  175.     set wh [winfo reqheight $data(w:window)]
  176.  
  177.     tixMapWindow $data(w:window)
  178.  
  179.     if {$data(-expandmode) == "expand"} {
  180.     if {$ww < $fw} {
  181.         set ww $fw
  182.     }
  183.     if {$wh < $fh} {
  184.         set wh $fh
  185.     }
  186.     }
  187.     if {$data(-shrink) == "x"} {
  188.     if {$fw < $ww} {
  189.         set ww $fw
  190.     }
  191.     }
  192.  
  193.     tixMoveResizeWindow $data(w:window) -$data(dx) -$data(dy) $ww $wh
  194.  
  195.     set first [expr $data(dx).0 / $ww.0]
  196.     set last  [expr $first + ($fw.0 / $ww.0)]
  197.     $data(w:hsb) set $first $last
  198.  
  199.     set first [expr $data(dy).0 / $wh.0]
  200.     set last  [expr $first + ($fh.0 / $wh.0)]
  201.     $data(w:vsb) set $first $last
  202. }
  203.  
  204. #----------------------------------------------------------------------
  205. # virtual functions to query the client window's scroll requirement
  206. #
  207. # When this function is called, the scrolled window is going to be
  208. # mapped, if it is still unmapped. Also, it is going to change its
  209. # size. Therefore, it is a good time to check whether the w:window needs
  210. # to be re-positioned due to the new parent window size.
  211. #----------------------------------------------------------------------
  212. proc tixScrolledWindow::GeometryInfo {w mW mH} {
  213.     upvar #0 $w data
  214.  
  215.     set bd \
  216.        [expr [$data(pw:f1) cget -bd] + [$data(pw:f1) cget -highlightthickness]]
  217.     set fw [expr $mW -2*$bd]
  218.     set fh [expr $mH -2*$bd]
  219.     set ww [winfo reqwidth  $data(w:window)]
  220.     set wh [winfo reqheight $data(w:window)]
  221.  
  222.     # Calculate the X info
  223.     #
  224.     if {$fw >= $ww} {
  225.     if {$data(dx) > 0} {
  226.         set data(dx) 0
  227.     }
  228.     set xinfo [list 0.0 1.0]
  229.     } else {
  230.     set maxdx [expr $ww - $fw]
  231.     if {$data(dx) > $maxdx} {
  232.         set data(dx) $maxdx
  233.     }
  234.     set first [expr $data(dx).0 / $ww.0]
  235.     set last  [expr $first + ($fw.0 / $ww.0)]
  236.     set xinfo [list $first $last]
  237.     }
  238.     # Calculate the Y info
  239.     #
  240.     if {$fh >= $wh} {
  241.     if {$data(dy) > 0} {
  242.         set data(dy) 0
  243.     }
  244.     set yinfo [list 0.0 1.0]
  245.     } else {
  246.     set maxdy [expr $wh - $fh]
  247.     if {$data(dy) > $maxdy} {
  248.         set data(dy) $maxdy
  249.     }
  250.     set first [expr $data(dy).0 / $wh.0]
  251.     set last  [expr $first + ($fh.0 / $wh.0)]
  252.     set yinfo [list $first $last]
  253.     }
  254.  
  255.     return [list $xinfo $yinfo]
  256. }
  257.